home *** CD-ROM | disk | FTP | other *** search
- /*
- File: OTGetDefaultEthernetAddress.c
-
- Contains: Demo of accessing OT from CodeWarrior 68K and
- Symantec for MPW 68K code resource.
-
- Written by: Quinn "The Eskimo!"
-
- Copyright: © 1996-8 by Apple Computer, Inc., all rights reserved.
-
- Change History (most recent first):
-
- */
-
- #define qDebug 1
-
- /////////////////////////////////////////////////////////////////////
- // Standard OT Interfaces
-
- #include <OpenTransport.h>
- #include <OpenTptLinks.h>
-
- /////////////////////////////////////////////////////////////////////
- // Low-Level OT Interfaces
-
- #include <OTDebug.h>
-
- // OTDebugStr is not defined in any OT header files, but it is
- // exported by the libraries, so we define the prototype here.
-
- extern pascal void OTDebugStr(const char* str);
-
- /////////////////////////////////////////////////////////////////////
- // Other Toolbox Interfaces
-
- #include <HyperXCMD.h>
- #include <TextUtils.h>
- #include <Strings.h>
-
- /////////////////////////////////////////////////////////////////////
- // Specical Envirnoment Dependent Stuff
-
- #if defined(__MWERKS__)
- #include <A4Stuff.h>
-
- extern UInt32 ZZZApplParamsHack[8];
-
- // Evil pseudo-LibraryManager stuff
-
- typedef long GlobalWorld;
-
- GlobalWorld GetCurrentGlobalWorld(void):__D0
- = {0x200D}; /* move.l A5,D0 */
-
- void SynchGlobalWorldFromA4(void)
- = {0x2A4C}; /* move.l A4,A5 */
-
- void SynchA4FromGlobalWorld(void)
- = {0x284D}; /* move.l A5,A4 */
-
- GlobalWorld SetCurrentGlobalWorld(GlobalWorld:__A0):__D0
- = {0x200D, /* move.l A5,D0 */
- 0x2A48}; /* move.l A0,A5 */
-
- #else
- #include <LibraryManagerUtilities.h>
- #include <LibraryManager.h>
- #endif
-
- /////////////////////////////////////////////////////////////////////
-
- // Forward definition for TrueMain
-
- static void TrueMain(XCmdPtr xpb);
-
- /////////////////////////////////////////////////////////////////////
- // Standard XCMD main entry point, one for each environment.
-
- #if defined(__MWERKS__)
-
- pascal void main(XCmdPtr xpb);
-
- pascal void main(XCmdPtr xpb)
- // Metrowerks main line.
- {
- long oldA4;
- GlobalWorld oldWorld;
- UInt32 *junk;
-
- Debugger();
-
- // Create a reference to our dummy AppParams globals and
- // assign it to a pointer. This prevents the linker
- // from dead-stripper the variable.
-
- junk = &ZZZApplParamsHack[1];
-
- // Now save A5, setup A4, and then setup A4 from A5.
-
- oldWorld = GetCurrentGlobalWorld();
-
- oldA4 = SetCurrentA4();
- SynchGlobalWorldFromA4();
-
- // Call the real code.
-
- TrueMain(xpb);
-
- // Clean up.
-
- (void) SetCurrentGlobalWorld(oldWorld);
- (void) SetA4(oldA4);
-
- // Debugger();
- }
-
- #else
-
- pascal void MAIN(XCmdPtr xpb)
- // Symantec main line.
- {
- OSStatus err;
- GlobalWorld oldWorld;
-
- Debugger();
-
- // Save A5 and then init our code resource's A5 world.
-
- oldWorld = GetCurrentGlobalWorld();
- err = InitCodeResource();
- if (err != noErr) {
- // No point using a DebugStr because the string would A5 relative
- // and this failure indicates that A5 could not be setup!
- Debugger();
- } else {
-
- // Call the real code.
-
- TrueMain(xpb);
-
- // Clean up.
-
- (void) SetCurrentGlobalWorld(oldWorld);
- FreeGlobalWorld();
- }
- // Debugger();
- }
-
- #endif
-
- /////////////////////////////////////////////////////////////////////
- // Generic OT Stuff
-
- struct EnetAddress {
- unsigned char bytes[6];
- };
- typedef struct EnetAddress EnetAddress, *EnetAddressPtr;
-
- typedef struct T8022Address T8022Address;
-
- static T8022Address gSimpleAddr = {
- AF_8022, // OTAddressType for 802 provider
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // hardware address, use zeros for bind requests
- 0x8888, // SAP / protocol type, value > 1500 implies ethernet protocol with no SNAP
- {0x00,0x00,0x00,0x00,0x00}
- };
-
- static OSStatus GetDefaultEthernetAddress(EnetAddressPtr defEnetAddr)
- // This routine returns the default Ethernet address of the machine
- // in the (6 byte) buffer pointed to by defEnetAddr.
- {
- OSStatus err;
- OSStatus junk;
- EndpointRef ep;
- TBind bindRequest;
- TBind bindResult;
- T8022Address resultAddr;
-
-
- ep = OTOpenEndpoint(OTCreateConfiguration(kEnetName), 0, 0, &err);
- if (err == kOTNoError) {
-
- // Setup bind request
-
- OTMemzero(&bindRequest, sizeof(TBind));
- bindRequest.addr.buf = (UInt8 *) &gSimpleAddr;
- bindRequest.addr.len = k8022BasicAddressLength; // family type + Ethernet + type field
-
- // Setup bind result
-
- OTMemzero(&bindResult, sizeof(TBind));
- bindResult.addr.buf = (UInt8 *) &resultAddr;
- bindResult.addr.maxlen = sizeof(resultAddr);
-
- // Call bind, which will return the MAC address
- // to which we're bound.
-
- err = OTBind(ep, &bindRequest, &bindResult);
- if (err == noErr) {
- BlockMoveData( resultAddr.fHWAddr, defEnetAddr->bytes, 6);
- }
-
- // Clean up.
-
- junk = OTCloseProvider(ep);
- OTAssert("GetDefaultEthernetAddress: Could not close endpoint", junk == noErr);
- }
- return err;
- }
-
- static char gHexDigits[16] = "0123456789ABCDEF";
-
- static void HexB(UInt8 b, char *buffer)
- {
- buffer[0] = gHexDigits[b >> 4];
- buffer[1] = gHexDigits[b & 0x0F];
- }
-
- static void TrueMain(XCmdPtr xpb)
- // Extra procedure wrapper to avoid horrible register caching problem
- // whereby the value of result was held in register A3 which was
- // setup from an A5 relative offset before our A5 had been set up
- // by InitCodeResource. Urgh!
- {
- OSStatus err;
- EnetAddress defEnetAddr;
- char result[256];
- short i;
-
- err = InitOpenTransport();
- if (err == noErr) {
-
- // Call OT to get the Ethernet address.
-
- err = GetDefaultEthernetAddress(&defEnetAddr);
-
- // Construct a formatted string from the Ethernet address.
-
- if (err == noErr) {
- OTStrCopy(result, "xx:xx:xx:xx:xx:xx");
- for (i = 0; i < 6; i++) {
- HexB(defEnetAddr.bytes[i], result + (3 * i));
- }
- }
-
- if (err != noErr) {
- OTStrCopy(result, "Error");
- }
-
- // Copy that string out to the returnValue handle.
-
- (void) PtrToHand((Ptr) result, &xpb->returnValue, OTStrLength(result) + 1);
-
- CloseOpenTransport();
- }
- }
-